import React, { useMemo, useState } from 'react'
import * as yup from 'yup'

type StepFormProps<T> = {
  initial: T
  steps: Array<{ title: string; fields: Array<{ key: keyof T; label: string; type?: string; placeholder?: string; required?: boolean }>; schema: yup.ObjectSchema<any> }>
  onSubmit: (value: T) => Promise<void> | void
}

export function StepForm<T extends Record<string, any>>({ initial, steps, onSubmit }: StepFormProps<T>): JSX.Element {
  const [value, setValue] = useState<T>(initial)
  const [step, setStep] = useState(0)
  const [errors, setErrors] = useState<Record<string, string>>({})
  const current = steps[step]

  const validate = async (): Promise<boolean> => {
    try {
      await current.schema.validate(value, { abortEarly: false })
      setErrors({})
      return true
    } catch (e: any) {
      const map: Record<string, string> = {}
      for (const err of e.inner || []) {
        if (err.path) map[err.path] = err.message
      }
      setErrors(map)
      return false
    }
  }

  const onNext = async () => {
    if (!(await validate())) return
    if (step < steps.length - 1) setStep(step + 1)
  }

  const onPrev = () => {
    if (step > 0) setStep(step - 1)
  }

  const onFinish = async () => {
    if (!(await validate())) return
    await onSubmit(value)
  }

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
        {steps.map((s, idx) => (
          <div key={idx} className="badge" style={{ background: idx === step ? 'rgba(59,130,246,0.12)' : undefined, borderColor: idx === step ? 'rgba(59,130,246,0.35)' : undefined }}>{idx + 1}. {s.title}</div>
        ))}
      </div>
      <div className="form-grid">
        {current.fields.map(f => (
          <div key={String(f.key)} className={f.type === 'password' ? 'field-3' : 'field'}>
            <label className="muted" style={{ display: 'block', marginBottom: 6 }}>{f.label}</label>
            <input
              className="input"
              type={f.type || 'text'}
              placeholder={f.placeholder}
              value={String(value[f.key] ?? '')}
              onChange={e => setValue({ ...value, [f.key]: f.type === 'number' ? Number(e.target.value) : e.target.value })}
            />
            {errors[String(f.key)] && <div style={{ color: 'salmon', marginTop: 4, fontSize: 12 }}>{errors[String(f.key)]}</div>}
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 12 }}>
        <button className="btn" onClick={onPrev} disabled={step === 0}>上一步</button>
        {step < steps.length - 1 ? (
          <button className="btn btn-primary" onClick={onNext}>下一步</button>
        ) : (
          <button className="btn btn-primary" onClick={onFinish}>提交</button>
        )}
      </div>
    </div>
  )
}

